﻿/*
 * Internet Connectivity Checker
 * Based on Microsoft NCSI implementation in Vista/Win7
 * 
 * By Kevin Pfister http://MrPfister.com
 */

namespace NCSI
{
    using System.Net;
    using System.IO;

    /// <summary>
    /// Provides Internet Connectivity State information based on
    /// Microsoft NCSI usage flow.
    /// </summary>
    public static class Connectivity
    {
        public enum ConnectionState
        {
            /// <summary>
            /// The interface is not connected to the internet
            /// </summary>
            NotConnected,

            /// <summary>
            /// The interface is connected to the internet however additional
            /// authentication may be required
            /// </summary>
            LimitedAccess,

            /// <summary>
            /// The interface has full connectivity to the internet
            /// </summary>
            Connected
        }

        /// <summary>
        /// Checks internet connectivity
        /// </summary>
        /// <returns>Connection State</returns>
        public static ConnectionState checkInternetConnectivity()
        {
            // Test 1: Check dns connection to dns.msftncsi.com
            try 
            {
            	IPHostEntry ipHost = Dns.GetHostEntry("dns.msftncsi.com");
            	if (ipHost.AddressList.Length == 0)
            	{
                    return ConnectionState.NotConnected;
            	}
            	else
            	{
                    // 131.107.255.255 is the DNS address of dns.msft.ncsi.com and shall not change
                    if (!ipHost.AddressList[0].ToString().Equals("131.107.255.255"))
                    {
                        return ConnectionState.LimitedAccess;
                    }
            	}
            }
            catch
            {
            	return ConnectionState.NotConnected;
            }

            // Test 2: DNS lookup to http://www.msftncsi.com and download ncsi.txt
            HttpWebRequest wReq = (HttpWebRequest)HttpWebRequest.Create("http://www.msftncsi.com/ncsi.txt");
            try
            {
                HttpWebResponse wRes = (HttpWebResponse)wReq.GetResponse();

                if (wRes.StatusCode != HttpStatusCode.OK)
                {
                    // The response is timing out or redirecting
                    return ConnectionState.LimitedAccess;
                }
                using (StreamReader sr = new StreamReader(wRes.GetResponseStream()))
                {
                    if (sr.ReadToEnd().Equals("Microsoft NCSI"))
                    {
                        return ConnectionState.Connected;
                    }
                    else
                    {
                        // A page can be downloaded but not correctly, possible redirection
                        return ConnectionState.LimitedAccess;
                    }
                }
            }
            catch
            {
                // If an error occurs, mark as no connection
                return ConnectionState.NotConnected;
            }

        }
    }
}
